package br.academia.arq.dao;

import java.util.Collection;
import java.util.HashMap;

import org.hibernate.HibernateException;
import org.hibernate.Query;

import br.academia.arq.erros.DAOException;
import br.academia.dominio.Cidade;
import br.academia.dominio.Estado;
import br.academia.util.Validador;


/**
 * Dao com operações referentes a Cidade
 * @see Cidade
 */
public class CidadeDAO extends GenericDAO{
	
	/**
	 * Método que retorna uma lista de Cidades que possua o
	 * nome idêntico ao nome passado como parâmetro
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Cidade> findCidadeByNome(String nome) throws HibernateException, DAOException{
		String hql = "select c from Cidade c where c.nome = :nome";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("nome", nome);
		
		@SuppressWarnings("unchecked")
		Collection<Cidade> cidades = q.list();
		
		return cidades;
	}
	
	/**
	 * Método que retorna uma lista de Cidades que possua o
	 * estado idêntico ao estado passado como parâmetro
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Cidade> findCidadeByEstado(Estado estado) throws HibernateException, DAOException{
		String hql = "select c from Cidade c left join c.estado e where e.id = :estadoId";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("estadoId", estado.getId());
		
		@SuppressWarnings("unchecked")
		Collection<Cidade> cidades = q.list();
		
		return cidades;
	}
	
	/**
	 * Método que retorna um lista de Cidades que possua o
	 * nome reduzido idêntico ao nome passado como parâmetro
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Cidade> findCidadeByNomeReduzido(String nomeReduzido) throws HibernateException, DAOException{
		String hql = "select c from Cidade c where c.nomeReduzido = :nomeReduzido";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("nomeReduzido", nomeReduzido);
		
		@SuppressWarnings("unchecked")
		Collection<Cidade> cidades = q.list();
		
		return cidades;
	}
	
	/**
	 * Método que retorna uma lista de Cidades que possua o
	 * nome e estado iguais ao nome e o estado passados como
	 * parâmetros
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Cidade findCidadeByNomeEstado(String nome, Estado estado) throws HibernateException, DAOException{
		String hql = "select c from Cidade c left join c.estado e where c.nome = :nome AND e.id = :estado ";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("nome", nome);
		q.setParameter("estado", estado.getId());
		
		Cidade cidades = (Cidade) q.uniqueResult();
		
		return cidades;
	}
	
	/**
	 * Método que retorna uma lista de Cidades que possua o
	 * nome reduzido e estado iguais aos passados como
	 * parâmetros
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Cidade findCidadeByNomeReduzidoEstado(String nomeReduzido, Estado estado) throws HibernateException, DAOException{
		String hql = "select c from Cidade c left join c.estado e where c.nomeReduzido = :nomeReduzido AND e.id = :estado ";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("nomeReduzido", nomeReduzido);
		q.setParameter("estado", estado.getId());
		
		Cidade cidades = (Cidade) q.uniqueResult();
		
		return cidades;
	}
	
	/**
	 * Método que retorna cargos que tenham nome ou descrição parecidos
	 * com os itens da cidade passado como parâmetro
	 * @param cidade
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Cidade> findCidadeLike(Cidade cidade) throws HibernateException, DAOException{
		String hql = "select c from Cidade c left join c.estado e where 1 = 1 ";
		HashMap<String, Object> parametros = new HashMap<String, Object>();
			
		if(!Validador.isEmpty(cidade.getNome())){
			hql += " and c.nome like :nome ";
			parametros.put("nome", "%" + cidade.getNome() + "%");
		}
		
		if(!Validador.isEmpty(cidade.getEstado())){
			hql += " and e.id = :estado ";
			parametros.put("estado", cidade.getEstado().getId());
		}
		
		Query q = getSession().createQuery(hql);
		
		setParametros(parametros, q);
		
		@SuppressWarnings("unchecked")
		Collection<Cidade> cidades = q.list();
		
		return cidades;
	}
}
